/* 
 * File:   Parser.cpp
 * Author: fliaali
 * 
 * Created on 30 de septiembre de 2013, 14:13
 */


#include "Parser.h"

#define NUMERO_STOPWORDS 116
#define A_LEER 1000

Parser::Parser() {

    //    const char* Lista_Stopwords[] = {"a","about","above","after","again","against","all","and","any","are","aren",
    //    "because","been","before","being","below","between","both","but","by","cannot","could","couldn","did",
    //    "didn","does","doesn","doing","don","down","during","each","few","for","from","further","had","hadn",
    //    "has","hasn","having","her","here","hers","herself","him","himself","his","how","into","isn",
    //    "its","itself","let","more","most","mustn","myself","nor","not","off","once","only","other","ought",
    //    "our","ours" ,"ourselves","out","over","own","same","shan","she","should","shouldn","some","such",
    //    "than","that","the","their","theirs","them","themselves","then","there","these","they","this","those",
    //    "through","too","under","until","very","was","wasn","were","weren","what","when","where","which","while",
    //    "who","whom","why","with","would","wouldn","you","your","yours","yourself","yourselves"};

    const char* Lista_Stopwords[] = {"myself", "doing", "then", "been", "having", "same", "weren", "against",
        "cannot", "few", "how", "our", "such", "under", "who", "about", "are", "between", "down", "had",
        "hasn", "itself", "once", "over", "should", "theirs", "those", "were", "where", "wouldn", "a", "after",
        "and", "because", "being", "but", "couldn", "don", "during", "each", "from", "hadn", "his", "into",
        "most", "not", "other", "ourselves", "some", "them", "they", "too", "was", "when", "which", "with",
        "above", "again", "all", "any", "aren", "before", "below", "both", "by", "could", "did", "didn", "does",
        "doesn", "for", "further", "has", "her", "here", "hers", "herself", "him", "himself", "isn", "its", "let",
        "more", "mustn", "nor", "off", "only", "ought", "ours", "out", "own", "shan", "she", "shouldn",
        "than", "that", "the", "their", "themselves", "there", "these", "this", "through", "until",
        "very", "wasn", "were", "what", "where", "while", "whom", "why", "would",
        "you", "your", "yours", "yourself", "yourselves"};
    Stopwords = abb_crear(strcmp, NULL);
    for (int i = 0; i < NUMERO_STOPWORDS; i++) {
        abb_guardar(Stopwords, Lista_Stopwords[i], NULL);
    }
}

Parser::~Parser() {
    abb_destruir(Stopwords);
}

bool Parser::Es_Separador(char letra) {
    if ((letra < 'a') || (letra > 'z')) {
        return true;
    }
    return false;
}

bool Parser::Es_Stopword(char* termino) {
    if (strlen(termino) < 3) return true;
    else return (abb_pertenece(Stopwords, termino));
}

void Parser::Armo_Shingles(char* shingle, char* termino, HashMin* mi_hashmin, Hashs* hash) {
    char aux[56];
    int i = 0;
    int largo_shingle = strlen(shingle);
    int largo_termino = strlen(termino);
    while (i < largo_termino) { // Opcion sin rotar
        shingle[largo_shingle] = termino[i];
        largo_shingle++;
        shingle[largo_shingle] = '\0';
        if (largo_shingle == 6) {
            mi_hashmin->Execute(hash->F_Hashing_Shingle(shingle));
            largo_shingle = 0;
            shingle[largo_shingle] = '\0';
        }
        i++;
    }
}



/*while((largo_shingle < 6) && (i < largo_termino)){   // Opcion Original
    shingle[largo_shingle] = termino[i];
    largo_shingle = strlen(shingle);
    i++;
    if(largo_shingle >= 6){
        shingle[6] = '\0';
    }
}
if((strlen(shingle) == 6)){
    if (i != 0) mi_hashmin->Execute(hash->F_Hashing_Shingle(shingle));*/
/*while(i < largo_termino){
    for(int j=0;j < 5; j++){
        shingle[j] = shingle[j+1];
    }
    shingle[5] = termino[i];
    i++;
    mi_hashmin->Execute(hash->F_Hashing_Shingle(shingle));
}*/

/*strncpy(aux,shingle,6);
strncpy(aux+6,termino,largo_termino);
while(i<largo_termino){
    strncpy(shingle,aux+i,6);
    mi_hashmin->Execute(hash->F_Hashing_Shingle(shingle));
    i++;
}
}     
}*/

void Clear(char* palabra, int l) {
    for (int i = 0; i < l; i++) {
        palabra[i] = '\0';
    }
}

void Parser::Obtener_Vector_HashMin(const char* archivo, char* ruta_final) {
    Log* lg = Log::getInstance();

    FILE* archivo_actual = fopen(archivo, "r");
    if (archivo_actual == NULL) {
        printf("Parser - Error al abrir archivo %s", archivo); //Logger
        return;
    }
    Hashs* mi_hash = new Hashs();
    //char* shingle = (char*) malloc(sizeof (char)*6);
    //char* termino = (char*) malloc(sizeof (char)*50);
    char shingle[6];
    char termino[50];
    
    char lectura[A_LEER];
    char letra;
    int i;

    Clear(shingle, 6);
    termino[0] = '\0';

    HashMin* mi_hashmin = new HashMin();
    int indice_termino = 0;

    //printf("Inicia Parseer %s \n", lg->getDateTimeNow().c_str());            
    while (!feof(archivo_actual)) {
        fread(lectura, sizeof (char), A_LEER, archivo_actual);
        if (!ferror(archivo_actual)) {
            i = 0;
            //printf("Inicio Proceso linea %s \n", lg->getDateTimeNow().c_str());
            while ((i < A_LEER)&&(lectura[i] != '\0')) {
                letra = tolower(lectura[i]);
                if (!(Parser::Es_Separador(letra))) {
                    termino[indice_termino] = letra;
                    indice_termino++;
                    termino[indice_termino] = '\0';
                } else {
                    if (!Es_Stopword(termino)) {
                        Armo_Shingles(shingle, termino, mi_hashmin, mi_hash);
                    }
                    termino[0] = '\0';
                    indice_termino = 0;
                }
                i++;
            }
        }
    }

    //printf("Fin Parseer %s \n", lg->getDateTimeNow().c_str());
    fclose(archivo_actual);
    //free(shingle);
    //free(termino);
    mi_hashmin->Save(ruta_final);
    mi_hashmin->Destruir();

}

void Parser::Destruir() {
    abb_destruir(Stopwords);
}

/*bool Escribo_Shingles(const char* clave, void* dato,void* archivo){
    fprintf((FILE*)archivo,"%s",clave);
    return true;
}

void Parser::Guardo_Shingles_En_Archivo(abb_t* arbol, char* nombre_archivo){
    FILE* archivo_shingles = fopen(nombre_archivo,"w");
    abb_in_order(arbol,Escribo_Shingles,archivo_shingles);
    abb_destruir(arbol);
    fclose(archivo_shingles); 
} 
 * 
 *Esta de mas */



